package com.example.demo.interceptor;

import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.springframework.stereotype.Component;

import java.util.Properties;

/**
 * SQL查询统计拦截器。</p>
 * @author xxx
 */
@Component
@Intercepts(
        {
                @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
                @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}),
        }
)
@Slf4j
public class SQLTimerInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        long startTime = System.currentTimeMillis();
        //OLAPQuery olap = null;
        try {
//            Method method = invocation.getMethod();
            //olap = method.getAnnotation(OLAPQuery.class);
//            if (!Objects.isNull(olap)) {
//                DynamicDataSourceContextHolder.push("olap");
//            }
            return invocation.proceed();
        } finally {
//            if (!Objects.isNull(olap)) {
//                DynamicDataSourceContextHolder.clear();
//            }

            long duration = System.currentTimeMillis() - startTime;
            SQLFormatHelper.PrintSQL printSql = SQLFormatHelper.getFormatSql(invocation);
            String sqlId = printSql.sqlId;
            String sql = printSql.formatSql;
            //忽略定时任务sql日志
            if(sql.startsWith("select task.* from dts_task") || sql.startsWith("select * from dts_base_info info")){
                // to do nothing
            }else {
                if (duration < 2000) {
                    //log.info("{} execute SQL: {} ms, \nSQL: {}", sqlId, duration, sql);
                } else if (duration < 5000) {
                    log.warn("{} execute SQL>1s: {} ms, \nSQL: {}", sqlId, duration, sql);
                } else if (duration < 10000) {
                    log.warn("{} execute SQL>=5s: {} ms, \nSQL: {}", sqlId, duration, sql);
                } else {
                    log.warn("{} execute SQL>=10s: {} ms, \nSQL: {}", sqlId, duration, sql);
                }
            }
        }
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {

    }

}